package edu.neu.cs6515.turn;

import java.util.List;

import com.google.java.contract.Ensures;
import com.google.java.contract.Requires;

import edu.neu.cs6515.xml.Placement;
import edu.neu.cs6515.xml.Score;
import edu.neu.cs6515.xml.Tile;

/**
 * Collection of methods of the proxy together with their contracts
 */
public interface ITurnProxy {

    /**
     * Allows player to put down a tile on the board
     * 
     * @param placement
     *            desired placement
     * @return List of size 1 of the placement was successful, empty list
     *         otherwise
     */
    @Requires({ "placement != null",
            "getErrorsInPlacement(placement).isEmpty()" })
    @Ensures({ "result != null", "result.size() == 0 || result.size() == 1" })
    List<Tile> placeTile(final Placement placement);

    /**
     * @param placement
     *            desired placement
     * @return list describing problems with placements, if empty the placement
     *         is legal
     */
    @Requires("placement != null")
    @Ensures("result.size() == 0 || result.size() == 1")
    List<String> getErrorsInPlacement(final Placement placement);

    /**
     * @return A copy of the list of tiles that are in the players hand
     */
    @Ensures({ "result != null", "result.size() <= 6" })
    List<Tile> getAllTilesInPlayersHand();

    /**
     * @return get all placement sofar since the beginning of the game
     */
    List<Placement> getAllPlacementsOnBoard();

    /**
     * @return A COPY of the current score of the player
     */
    @Ensures("result != null")
    Score getCurrentScore();

    /**
     * @return Result object that informs about the outcome of a turn
     */
    @Ensures("result >= 0")
    int getRequiredPlacements();

    /**
     * reRack tiles in player's hand, assuming both player's hand and tile bag
     * have at least 6 tiles
     */
    void reRack();

    /**
     * @return true if the player can re-rack
     */
    boolean isReRackable();

    /**
     * 
     * @return the placements that was placement in this turn
     */
    List<Placement> getPlacementsInThisTurn();

}